package com.onpositive.dataminer.core;

import java.util.Collection;
import java.util.Set;

import com.onpositive.data.IPropertyConstants;
import com.onpositive.dataminer.core.PropertyRateAuditResult;
import com.onpositive.knowledge.model.value.audits.AbstractAuditResult;
import com.onpositive.knowledge.model.value.audits.AuditSourceContainer;
import com.onpositive.knowledge.model.value.audits.IValueAudit;
import com.onpositive.knowledge.model.values.DescribedValue;
import com.onpositive.semantic.model.api.meta.DefaultMetaKeys;
import com.onpositive.semantic.model.api.property.IProperty;
import com.onpositive.units.ParsedDate;
import com.onpositive.units.ParsedDimension;
import com.onpositive.units.ParsedScalar;
import com.onpositive.units.ParsedValue;

public class PropertyRateAudit extends AuditSourceContainer implements
		IValueAudit {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static final String ID = "property-rate-audit";

	@Override
	public void perform(IProperty prop, Iterable<Object> objects,
			AbstractAuditResult auditResult) {
		if (!(auditResult instanceof PropertyRateAuditResult))
			return;
		
		PropertyRateAuditResult r = (PropertyRateAuditResult) auditResult;
		double objectCount = 0;
		int cC=0;
		// double totalCount=0;
		for (Object o : objects) {
			// totalCount++;
			if (DefaultUniverse.getInstance().isInteresting(o)) {
				objectCount++;
				Object value = prop.getValue(o);
				if (value == null) {
					r.addAsSuspicious(o);
					continue;
				}
				boolean isCorrect = false;
				if (value instanceof DescribedValue){
					DescribedValue vl=(DescribedValue) value;
					value=vl.value();
				}
				if (value instanceof Collection){
					Collection c=(Collection) value;
					for (Object q:c){
						isCorrect = q(prop, q, isCorrect);
						if(isCorrect){
							break;
						}
					}
				}
				if (value instanceof ParsedValue) {
					isCorrect = q(prop, value, isCorrect);
				}
				if (value instanceof Object[]) {
					Object[] mn = (Object[]) value;
					if (mn.length == 0) {
						r.addAsSuspicious(o);
						continue;
					}
				}
				if (isCorrect)
						{
					cC++;
						}
				r.totalEncountered++;
			}
		}
		r.rate = r.totalEncountered / objectCount;
		r.correctTypeCount=cC;
		r.correctTypeRate = cC / objectCount;
	}

	protected boolean q(IProperty prop, Object value, boolean isCorrect) {
		if (value instanceof DescribedValue){
			DescribedValue vl=(DescribedValue) value;
			value=vl.value();
		}
		ParsedValue vm = (ParsedValue) value;
		String stringValue = DefaultMetaKeys.getStringValue(prop,
				IPropertyConstants.CHAR_PARSER_ID_LABEL);
		String pValue = DefaultMetaKeys.getStringValue(prop,
				IPropertyConstants.CHAR_PRIMARY_UNIT_LABEL);
		if (stringValue.equals(ParsedDimension.ID)) {
			Collection<ParsedDimension> values = vm
					.getValues(ParsedDimension.class);
			if (!values.isEmpty()) {
				for (ParsedDimension m : values) {
					if (m.getUnit().getPrimaryUnit().getShortName().equals(pValue)){
						isCorrect=true;
						break;
					}
				}
			}
		}
		if (stringValue.equals(ParsedScalar.ID)) {
			Collection<ParsedScalar> values = vm
					.getValues(ParsedScalar.class);
			if (!values.isEmpty()) {
				for (ParsedScalar m : values) {
					if (!(m instanceof ParsedDimension)) {
						isCorrect = true;
						break;
					}
				}
			}
		}
		if (stringValue.equals(ParsedDate.ID)) {
			Collection<ParsedDate> values = vm
					.getValues(ParsedDate.class);
			if (!values.isEmpty()) {
				isCorrect = true;
			}
		}
		return isCorrect;
	}

	@Override
	public AbstractAuditResult createAuditResult(IProperty prop) {
		return new PropertyRateAuditResult(prop);
	}

	@Override
	public Set<String> getRequiredAudits() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getId() {
		return ID;
	}

}
